home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Game-Power
/
Amiga Game-Power.iso
/
pd mix ii
/
click to front
/
viacom
/
oddblit.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-05-20
|
4KB
|
151 lines
/* :ts=8 bk=0
*
* oddblit.c: Custom blitter routine. Stolen from Tomas Rokicki's LIFE
* program and mashed up beyond all recognition. Nearly all
* comments are Tom's.
*
* Leo L. Schwab 8706.4
*/
#include <exec/types.h>
/*
* This include file includes the defines for all the blitter functions.
* It only allows use of the `blit' operations; for area fills or line
* drawing, it will need to be extended.
*
* Information gleaned from the Hardware Reference Manual.
*/
#define BLTADD (0xdff040L)
/*
* This structure contains everything we need to know.
* Do not do a structure copy into this! Instead, assign
* each field. The last field assigned must be bltsize; that
* starts up the blitter. Also note that all of these are
* write only, and you can't read them.
*/
struct bltstruct {
short con0;
short con1;
short afwm;
short alwm;
short *csource, *bsource, *asource, *dsource;
short bltsize;
short dmy1, dmy2, dmy3;
short cmod, bmod, amod, dmod;
} *blitter = BLTADD;
/*
* We need an array which tells what to use for all 256 possible operations.
*/
#define USEA (0x8)
#define USEB (0x4)
#define USEC (0x2)
#define USED (0x1)
char touse[256];
char fwma[16];
char lwma[16];
/*
* Call initblitdata() once on startup before you ever call oddblit.
*/
initblitdata()
{
register int i;
register int s;
for (i=0; i<256; i++) {
s = USED;
if ((i >> 4) != (i & 15))
s += USEA;
if (((i >> 2) & 51) != (i & 51))
s += USEB;
if (((i >> 1) & 85) != (i & 85))
s += USEC;
touse[i] = s;
}
s = 0xffff;
for (i=0; i<16; i++) {
fwma[i] = s;
s = (s >> 1) & ~0x8000 ;
lwma[i] = 0xffff - s;
}
}
/*
* (Tom's original speech:)
* This is the major user interface. Takes addresses and offsets for
* all four locations, a modulo and sizes, and a function.
* Assumes the modulos for all sources and destination are the same.
* You might want to add some arguments or delete some.
*
* All arguments are in pixels (except the addresses and function.)
*
* Before you call this routine, call OwnBlitter(); after you have
* called it as many times as you need, call DisownBlitter(). Remember
* that you cannot do any printf's or anything else which requires the
* blitter when you own the blitter, so be careful with the debug code.
* The machine will lock but will not crash.
*/
/*
* Leo here. This is the bit I mashed to pieces. Using Tom's BlitLab
* program (wonderful thing), I figured out what it was I wanted to do.
* So sit back, relax, and enjoy the narrative to follow...
*
* It is assumed that src and dest bitmap are identically sized,
* and that the noise bitmap is larger than both of them.
* All x,y parameters are in pixels.
*
* Note that this does NOT do a general arbitrary rectangle to rectangle
* logic function. It's just a quick hack to OR random bits from one
* bitplane with another, and place the result into a third location.
*/
oddblit (src, dest, sdx, sdy,
noise, nx, ny,
xoff, yoff, minterm)
short *src, *dest, *noise;
int sdx, sdy, nx, ny, xoff, yoff;
int minterm;
{
int noisemod;
/* Compute width of bitplanes in words */
sdx = (sdx + 15) >> 4;
nx = (nx + 15) >> 4;
/* noisemod is in bytes */
noisemod = (nx - sdx) * 2;
/* Wait for blitter to finish whatever it may be doing */
WaitBlit ();
/* Start tromping the blitter */
blitter -> bsource = src;
blitter -> dsource = dest;
blitter -> afwm = blitter -> alwm = 0xffff;
/* Compute start address into noise plane */
blitter -> asource = noise + yoff * nx + (xoff >> 4);
/* Compute desired shift for noise plane */
xoff &= 15;
/* Comnpute and write control words */
blitter -> con0 = (xoff << 12) + (touse[minterm] << 8) + minterm;
blitter -> con1 = 0; /* No shifts on B source or flags */
/* Write out the modulos */
blitter -> amod = noisemod;
blitter -> bmod = 0; /* These are sized precisely */
blitter -> dmod = 0;
/*
* This last assignment starts up the blitter.
*/
blitter->bltsize = (sdy << 6) + sdx;
}